import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.Serializable;
import java.util.HashMap;

import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;

public class CardTable extends JPanel implements Serializable{
	private CardTable thisTable;
	private HashMap<String, Counter> counters;
	private HashMap<String, CardStack> stacks;
	public CardTable() {
		thisTable = this;
		setLayout(null);
		setPreferredSize(new Dimension(700,500));
		setBackground(Color.GREEN);
		addMouseListener(new PopClickListener());
		counters = new HashMap<String, Counter>();
		stacks = new HashMap<String, CardStack>();
	}
	public Counter getCounter(String name) {
		return counters.get(name);
	}
	public void addCounter(String name, int x, int y) {
		Counter newCounter = new Counter(name);
		add(newCounter);
		newCounter.setBounds(x, y, newCounter.getMinimumSize().width, newCounter.getMinimumSize().height);
		counters.put(name, newCounter);
		validateTree();
	}
	
	public Counter[] getAllCounters(){
		Counter[] erg = new Counter[counters.size()];
		counters.keySet().toArray(erg);
		return erg;
	}
	
	public CardStack[] getAllStacks(){
		CardStack[] erg = new CardStack[stacks.size()];
		stacks.keySet().toArray(erg);
		return erg;
	}
	
	/**
	 * adds a new Stack to the cardtable
	 * @param name the name of the new CardStack
	 * @param x it's x-axis position
	 * @param y it's y-axis position
	 * @param cards a String Array of the names of the cards in the new CardStack or the name of the file
	 */
	public void addStack(String name, int x, int y, String[] cards) {
		CardStack newStack;
		if(cards != null){
			if(cards.length>=1 && cards[0].endsWith(".txt")){
				newStack = new CardStack(name, cards[0]);
			}
			else{			
				newStack = new CardStack(name);
				for(int i = 0; i<cards.length; i++){
					newStack.insertOnTop(new Card(cards[0]));
				}
			}
		}
		else{
			newStack = new CardStack(name);
		}
		add(newStack);
		newStack.setBounds(x, y, newStack.getMinimumSize().width, newStack.getMinimumSize().height);
		stacks.put(name, newStack);
		validateTree();
	}
	
	public CardStack getCardStack(String name) {
		return stacks.get(name);
	}
	public void moveObject(String name, int x, int y) {
		Component mv = counters.get(name);
		if (mv == null)
			mv = stacks.get(name);
		if (mv != null) {
			mv.setBounds(x, y, mv.getMinimumSize().width, mv.getMinimumSize().height);
		}
	}
	
	class PopClickListener implements MouseListener {
		public void mousePressed(MouseEvent e) {
			if (e.isPopupTrigger())
	    		doPop(e);
		}
		public void mouseReleased(MouseEvent e) {
			if (e.isPopupTrigger())
	            doPop(e);
		}
		
		private void doPop(MouseEvent e){
	        PopUpMenu menu = new PopUpMenu(e.getPoint());
	        menu.show(e.getComponent(), e.getX(), e.getY());
	    }
		
		public void mouseEntered(MouseEvent e) {
		}
		public void mouseExited(MouseEvent e) {	
		}
		public void mouseClicked(MouseEvent e) {
		}
	}
	
	class PopUpMenu extends JPopupMenu {
		private Point p;
		public PopUpMenu(Point p) {
			this.p = p;
			JMenuItem createStack = new JMenuItem("Create new Cardstack");
			createStack.addActionListener(new TableActionListener(p));
			this.add(createStack);
			JMenuItem createCounter = new JMenuItem("Create new Counter");
			createCounter.addActionListener(new TableActionListener(p));
			this.add(createCounter);
		}
	}
	
	class TableActionListener implements ActionListener {
		private Point p;
		public TableActionListener(Point p) {
			this.p = p;
		}
		public void actionPerformed(ActionEvent e) {
			if (((JMenuItem) e.getSource()).getText().equals("Create new Counter")) {
				String retV = JOptionPane.showInputDialog("Name for the counter");
				Game.getGame().client.sendCreateCounter(retV, p.x, p.y);
			}
			else if (((JMenuItem) e.getSource()).getText().equals("Create new Cardstack")) {
				//handleNewCardStack();
				String name = JOptionPane.showInputDialog("Name of the Cardstack");
				String cards = JOptionPane.showInputDialog("Deckname or space-seperated list of card-names");
				Game.getGame().client.sendCreateStack(name, p.x, p.x, cards);
			}
		}
		/**
		 * handles the event of a new CardStack
		 */
		public void handleNewCardStack(){
			//TODO: Should eventually open a specialized window
			String name = JOptionPane.showInputDialog("Name of the Cardstack");
			//CardStack newCS = new CardStack(name);
			String cards = JOptionPane.showInputDialog("Deckname or space-seperated list of card-names");
			/*if(cards[0].endsWith(".txt")){
				newCS.fillDeck(retV);
			}
			else{
				for (String card: cards) {
					newCS.insertOnTop(new Card(card));
				}
			}		
			newCS.addLogListener(new LogListener(Game.getGame().getLog()));
			thisTable.add(newCS);
			newCS.setBounds(p.x, p.y, newCS.getMinimumSize().width, newCS.getMinimumSize().height);
			thisTable.validateTree();*/
			//thisTable.addStack(name, p.x, p.y, cards);
			//getCardStack(name).addLogListener(new LogListener(Game.getGame().getLog()));
			Game.getGame().client.sendCreateStack(name, p.x, p.x, cards);
		}
	}
}
